#!/usr/bin/python

import os,sys
import re
import string
from sets import Set


PCP = 0
TMP = 1
PDSI = 2

def fatal():
    sys.exit()

class climateData:
    """A class for climate data"""

    def __init__(self, filename):
        self.filename = filename

	#this variable records which columns the three environmental indices are bound to
	self.targets = {"YearMonth":-1, "PCP":-1, "TMP":-1, "PDSI":-1}

	#we use the sets to eliminate multiples years and multiples months
	#so that we can obtain the actual range of years and months of the input data
	self.__months = Set([])
	self.__years = Set([])

	#the dictionary used to record all the data requireed to process from the input
	self.__data = {}
    # parse the input file and store the data
    # in an internal format. I suggest using 
    # a dictionary for mapping pairs of year
    # and month to climate data: (pcp, temp, pdsi)
    def parseFile(self):
	

	fileptr = open(self.filename)
	lines_count = 0
	for line in fileptr:
		lines_count = lines_count + 1
		if lines_count == 1:
			#the regular experssion of words
			words = re.findall(r"\w+", line)
			for target in self.targets.keys():
				for w in words:
					if target == w:
						self.targets[target] = words.index(target);

		else:
			#the regular expression of the numbers, no matter of the type digital or float
			figures = re.findall(r"-?\d+.?\d*", line)
			ym = figures[self.targets["YearMonth"]]
			self.__years.add(string.atoi(ym[0:4]))
			self.__months.add(string.atoi(ym[4:6]))

			#add all the information necessary to the dictionary
			self.__data[(string.atoi(ym[0:4]), string.atoi(ym[4:6]))] =\
			(string.atof(figures[self.targets["PCP"]]), string.atof(figures[self.targets["TMP"]]), string.atof(figures[self.targets["PDSI"]]))
	#find the correct range of years and month of input
	self.__months = list(self.__months)
	self.__years = list(self.__years)
	self.__months.sort()
	self.__years.sort()
	fileptr.close()	
    
    # report monthly average data
    def reportMonthlyAverage(self):
	print "Reporting monthly average:"
	for month in self.__months:
		avg = [0] * 3
		count = [0] * 3
		for (y,m) in self.__data.keys():
			if m == month:
				avg[PCP] = avg[PCP] + self.__data[(y,m)][PCP]
				count[PCP] = count[PCP] + 1
		for(y,m) in self.__data.keys():
			if m == month:
				avg[TMP] = avg[TMP] + self.__data[(y,m)][TMP]
				count[TMP] = count[TMP] + 1
		for(y,m) in self.__data.keys():
			if m == month:
				avg[PDSI] = avg[PDSI] + self.__data[(y,m)][PDSI]
				count[PDSI] = count[PDSI] + 1

		avg[PCP] = avg[PCP]/count[PCP]
		avg[TMP] = avg[TMP]/count[TMP]
		avg[PDSI] = avg[PDSI]/count[PDSI]
		print "  Month %d  average PCP: %.3g  average temperature: %.4g  average PDSI: %.2f" %(month, avg[PCP],avg[TMP], avg[PDSI])

    # report yearly data
    def reportYearlyData(self):
	print "\nReporting yearly data:"
	for year in self.__years:
		avg = [0] * 2
		count = [0] * 2
		num_droughts = 0
		for (y,m) in self.__data.keys():
			if y == year:
				avg[PCP] = avg[PCP] + self.__data[(y,m)][PCP]
				count[PCP] = count[PCP] + 1
		for (y,m) in self.__data.keys():
			if y == year:
				avg[TMP] = avg[TMP] + self.__data[(y,m)][TMP]
				count[TMP] = count[TMP] + 1
		for (y,m) in self.__data.keys():
			if y == year and self.__data[(y,m)][PDSI] <= -3.0:
				num_droughts = num_droughts + 1
		
		avg[PCP] = avg[PCP]/count[PCP]
		avg[TMP] = avg[TMP]/count[TMP]
		print "  Year %d   average PCP: %.3g inches   average temp: %.4g   num of droughts: %d" %(year, avg[PCP], avg[TMP], num_droughts)
    # report decade long data
    def reportDecadeLongData(self):
	print "\nReporting decade-long data:"
	
	decades = []
	y_start = self.__years[0]
	while y_start + 9 in self.__years:
		decades.append((y_start, y_start + 9))
		y_start = y_start + 10

	for decade in decades:
		avg = [0] * 2
		count = [0] * 2
		num_droughts = 0
		for (y,m) in self.__data.keys():
			if y >= decade[0] and y <= decade[1]:
				avg[PCP] = avg[PCP] + self.__data[(y,m)][PCP]
				count[PCP] = count[PCP] + 1
		for (y,m) in self.__data.keys():
			if y >= decade[0] and y <= decade[1]:
				avg[TMP] = avg[TMP] + self.__data[(y,m)][TMP]
				count[TMP] = count[TMP] + 1
		for (y,m) in self.__data.keys():
			if y >= decade[0] and y <= decade[1] and self.__data[(y,m)][PDSI] < -3.0:
				num_droughts = num_droughts + 1
		
		avg[PCP] = avg[PCP]/count[PCP]
		avg[TMP] = avg[TMP]/count[TMP]
		print "  Decade %d--%d   average PCP: %.3g inches   average temp: %.4g   num of droughts: %d" %(decade[0], decade[1], avg[PCP], avg[TMP], num_droughts)
# the main program

if (len(sys.argv) > 1):
    	filename = sys.argv[1]
else: 
    	print 'Please give a file name that contains the climate data! Exiting ...'
    	fatal()

g = climateData (filename)
g.parseFile()
g.reportMonthlyAverage()
g.reportYearlyData()
g.reportDecadeLongData()
